package com.ljx.designMode.singleMode;

/**
 * @author LJX
 * @Description: 单例模式中的懒汉模式（会出现线程安全问题）
 * @Date: 2022/11/7 10:33
 * @Version 1.0
 */
public class SingleModeLazySafe {
	/**
	 * 对于getInstance()方法来说，绝大部分的操作都是读操作，读操作是线程安全的，所以我们没必要
	 * 让每个线程都必须持有锁才能调用该方法，我们只需要调整加锁的机制
	 * ，由此也产生了一种新的实现模式：双重检查锁模式
	 * （其实就是在第一次调用的时候加锁，其他再调用的时候不需要加锁）
	 * 双重检查锁模式是一种非常好的单例实现模式，解决了单例、性能、线程安全问题，
	 * 上面的双重检测锁模式看上去完美无缺，其实是存在问题，在多线程的情况下，
	 * 可能会出现空指针问题，出现问题的原因是JVM在实例化对象的时候会进行优化和指令重排序操作。
	 * 要解决双重检查锁模式带来空指针异常的问题，只需要使用 `volatile`(易变的，动荡不安的) 关键字, `volatile`
	 * 关键字可以保证可见性和有序性。
	 */
	private  static volatile SingleModeLazySafe singleModeLazy;

	private SingleModeLazySafe() {
	}

	public static SingleModeLazySafe getInstance(){
		// 如果多个线程进来后发现singleModeLazy，则无需再获取锁对象
		if(singleModeLazy==null){
			synchronized (SingleModeLazy.class){
				// 如果对象不等于空，则无需创建对象
			if (singleModeLazy==null){
				singleModeLazy=new SingleModeLazySafe();
				}
			}
		}

		return singleModeLazy;
	}
}
